﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using Dng.Application.Logging;
using ShippingManage.DataAccessor.Entities;
using ShippingManage.Models;
using System.Drawing;
using System.Drawing.Printing;

namespace ShippingManage.Reports
{
	public partial class frmCargoManifest : FormBase
	{
		// for Invoice Head:
		private string InvTitle;
		private string InvSubTitle1;
		private string InvSubTitle2;
		private string InvSubTitle3;
		private string InvImage;

		// for Report:
		private int _currentY;
		private int _currentX;
		private int _leftMargin;
		private int _rightMargin;
		private int _topMargin;
		private int _bottomMargin;
		private int _invoiceWidth;
		private int _invoiceHeight;
		private string _customerName;
		private string _customerCity;
		private string _sellerName;
		private string _saleID;
		private string _saleDate;
		private decimal _saleFreight;
		private decimal _subTotal;
		private decimal _invoiceTotal;
		private bool _readInvoice;
		private int _amountPosition;

		// Font and Color:------------------
		// Title Font
		private Font _invTitleFont = new Font("Arial", 24, FontStyle.Regular);
		// Title Font height
		private int _invTitleHeight;
		// SubTitle Font
		private Font _invSubTitleFont = new Font("Arial", 14, FontStyle.Regular);
		// SubTitle Font height
		private int _invSubTitleHeight;
		// Invoice Font
		private Font _invoiceFont = new Font("Arial", 12, FontStyle.Regular);
		// Invoice Font height
		private int _invoiceFontHeight;
		// Blue Color
		private SolidBrush _blueBrush = new SolidBrush(Color.Blue);
		// Red Color
		private SolidBrush _redBrush = new SolidBrush(Color.Red);
		// Black Color
		private SolidBrush _blackBrush = new SolidBrush(Color.Black);

		public frmCargoManifest()
		{
			InitializeComponent();
		}

		List<CargoManifest> _cargoManifest = null;
		private void SearchButton_Click(object sender, EventArgs e)
		{
			try
			{
				if (!SearchOnLocalCheckBox.Checked)
				{
					ShippingManageServices.ShippingManageService service = new ShippingManageServices.ShippingManageService();
					CargoManifestGrid.DataSource = service.SearchHAWB();
				}
				else
				{
					HouseAirWayBillModel model = new HouseAirWayBillModel();
					_cargoManifest = model.SearchHAWB(
						_recordsPerPage,
						_currentPage,
						out _totalPage,
						txtPrepaidBy.Text.Trim(),
						txtConsolNo.Text.Trim(),
						txtConsignee.Text.Trim(),
						txtConsigneeTel.Text.Trim(),
						txtConsigneeFax.Text.Trim(),
						Dng.Utilities.Services.I.S2DT(txtDate.Text.Trim()),
						txtM_AWB.Text.Trim(),
						txtAirportOfDept.Text.Trim(),
						txtAirportOfDest.Text.Trim(),
						txtFTPNo.Text.Trim(),
						Dng.Utilities.Services.I.S2DT(txtETD.Text.Trim()),
						Dng.Utilities.Services.I.S2DT(txtETA.Text.Trim()),
						txtCarrier.Text.Trim());

					CargoManifestGrid.DataSource = _cargoManifest;
				}

				msg.Text = "Found " + _cargoManifest.Count + " HAWB Item(s)";
			}
			catch (Exception ex)
			{
				msg.Text = ex.Message;
				Log.Error(ex, "Search HAWB failed.");
			}
		}

		#region Validate data

		#endregion

		private void txtConsolNo_Validating(object sender, CancelEventArgs e)
		{
			if (!IsRequireFieldValid(sender))
				ShowError(sender, e, "Please enter a Consol NO");
		}

		bool IsRequireFieldValid(object sender)
		{
			return ((TextBox)sender).Text.Trim().Length > 0;
		}

		bool IsDateTimeValid(object sender)
		{
			bool result = false;

			try
			{
				Dng.Utilities.Services.I.S2DT(((TextBox)sender).Text.Trim());
				result = true;
			}
			catch
			{
			}

			return result;
		}

		void ShowError(object sender, CancelEventArgs e, string message)
		{
			e.Cancel = true;
			errorProvider1.SetError((Control)sender, message);
		}

		private void txtDate_Validating(object sender, CancelEventArgs e)
		{
			if (!IsDateTimeValid(sender))
				ShowError(sender, e, "Please enter a valid Date field value");
		}

		private void txtETD_Validating(object sender, CancelEventArgs e)
		{
			if (!IsDateTimeValid(sender))
				ShowError(sender, e, "Please enter a valid ETD field value");
		}

		private void txtETA_Validating(object sender, CancelEventArgs e)
		{
			if (!IsDateTimeValid(sender))
				ShowError(sender, e, "Please enter a valid ETA field value");
		}

		private void frmCargoManifest_Load(object sender, EventArgs e)
		{
			CargoManifestGrid.AutoGenerateColumns = false;
		}

		private void PrintDialogButton_Click(object sender, EventArgs e)
		{

		}

		private void PrintPreviewButton_Click(object sender, EventArgs e)
		{

		}

		private void PrintButton_Click(object sender, EventArgs e)
		{

		}

		private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
		{
			_leftMargin = (int)e.MarginBounds.Left;
			_rightMargin = (int)e.MarginBounds.Right;
			_topMargin = (int)e.MarginBounds.Top;
			_bottomMargin = (int)e.MarginBounds.Bottom;
			_invoiceWidth = (int)e.MarginBounds.Width;
			_invoiceHeight = (int)e.MarginBounds.Height;

			if (!_readInvoice)
				ReadInvoiceData();

			SetInvoiceHead(e.Graphics); // Draw Invoice Head
			SetOrderData(e.Graphics); // Draw Order Data
			SetInvoiceData(e.Graphics, e); // Draw Invoice Data

			_readInvoice = true;
		}

		private void SetInvoiceHead(Graphics g)
		{
			ReadInvoiceHead();

			_currentY = _topMargin;
			_currentX = _leftMargin;
			int ImageHeight = 0;

			// Draw Invoice image:
			if (System.IO.File.Exists(InvImage))
			{
				Bitmap oInvImage = new Bitmap(InvImage);
				// Set Image Left to center Image:
				int xImage = _currentX + (_invoiceWidth - oInvImage.Width) / 2;
				ImageHeight = oInvImage.Height; // Get Image Height
				g.DrawImage(oInvImage, xImage, _currentY);
			}

			_invTitleHeight = (int)(_invTitleFont.GetHeight(g));
			_invSubTitleHeight = (int)(_invSubTitleFont.GetHeight(g));

			// Get Titles Length:
			int lenInvTitle = (int)g.MeasureString(InvTitle, _invTitleFont).Width;
			int lenInvSubTitle1 = (int)g.MeasureString(InvSubTitle1, _invSubTitleFont).Width;
			int lenInvSubTitle2 = (int)g.MeasureString(InvSubTitle2, _invSubTitleFont).Width;
			int lenInvSubTitle3 = (int)g.MeasureString(InvSubTitle3, _invSubTitleFont).Width;
			// Set Titles Left:
			int xInvTitle = _currentX + (_invoiceWidth - lenInvTitle) / 2;
			int xInvSubTitle1 = _currentX + (_invoiceWidth - lenInvSubTitle1) / 2;
			int xInvSubTitle2 = _currentX + (_invoiceWidth - lenInvSubTitle2) / 2;
			int xInvSubTitle3 = _currentX + (_invoiceWidth - lenInvSubTitle3) / 2;

			// Draw Invoice Head:
			if (InvTitle != "")
			{
				_currentY = _currentY + ImageHeight;
				g.DrawString(InvTitle, _invTitleFont, _blueBrush, xInvTitle, _currentY);
			}
			if (InvSubTitle1 != "")
			{
				_currentY = _currentY + _invTitleHeight;
				g.DrawString(InvSubTitle1, _invSubTitleFont, _blueBrush, xInvSubTitle1, _currentY);
			}
			if (InvSubTitle2 != "")
			{
				_currentY = _currentY + _invSubTitleHeight;
				g.DrawString(InvSubTitle2, _invSubTitleFont, _blueBrush, xInvSubTitle2, _currentY);
			}
			if (InvSubTitle3 != "")
			{
				_currentY = _currentY + _invSubTitleHeight;
				g.DrawString(InvSubTitle3, _invSubTitleFont, _blueBrush, xInvSubTitle3, _currentY);
			}

			// Draw line:
			_currentY = _currentY + _invSubTitleHeight + 8;
			g.DrawLine(new Pen(Brushes.Black, 2), _currentX, _currentY, _rightMargin, _currentY);
		}

		private void SetOrderData(Graphics g)
		{// Set Company Name, City, Salesperson, Order ID and Order Date
			string fieldValue = "";
			_invoiceFontHeight = (int)(_invoiceFont.GetHeight(g));
			// Set Company Name:
			_currentX = _leftMargin;
			_currentY = _currentY + 8;
			fieldValue = "Company Name: " + _customerName;
			g.DrawString(fieldValue, _invoiceFont, _blackBrush, _currentX, _currentY);
			// Set City:
			_currentX = _currentX + (int)g.MeasureString(fieldValue, _invoiceFont).Width + 16;
			fieldValue = "City: " + _customerCity;
			g.DrawString(fieldValue, _invoiceFont, _blackBrush, _currentX, _currentY);
			// Set Salesperson:
			_currentX = _leftMargin;
			_currentY = _currentY + _invoiceFontHeight;
			fieldValue = "Salesperson: " + _sellerName;
			g.DrawString(fieldValue, _invoiceFont, _blackBrush, _currentX, _currentY);
			// Set Order ID:
			_currentX = _leftMargin;
			_currentY = _currentY + _invoiceFontHeight;
			fieldValue = "Order ID: " + _saleID;
			g.DrawString(fieldValue, _invoiceFont, _blackBrush, _currentX, _currentY);
			// Set Order Date:
			_currentX = _currentX + (int)g.MeasureString(fieldValue, _invoiceFont).Width + 16;
			fieldValue = "Order Date: " + _saleDate;
			g.DrawString(fieldValue, _invoiceFont, _blackBrush, _currentX, _currentY);

			// Draw line:
			_currentY = _currentY + _invoiceFontHeight + 8;
			g.DrawLine(new Pen(Brushes.Black), _leftMargin, _currentY, _rightMargin, _currentY);
		}

		int _recordsPerPage = 20; // twenty items in a page
		int _currentPage = 1;
		int _totalPage = 1;
		private void SetInvoiceData(Graphics g, PrintPageEventArgs e)
		{// Set Invoice Table:
			string fieldValue = "";
			int currentRecord = 0;
			
			decimal Amount = 0;
			bool StopReading = false;

			// Set Table Head:
			int xProductID = _leftMargin;
			_currentY = _currentY + _invoiceFontHeight;
			g.DrawString("Product ID", _invoiceFont, _blueBrush, xProductID, _currentY);

			int xProductName = xProductID + (int)g.MeasureString("Product ID", _invoiceFont).Width + 4;
			g.DrawString("Product Name", _invoiceFont, _blueBrush, xProductName, _currentY);

			int xUnitPrice = xProductName + (int)g.MeasureString("Product Name", _invoiceFont).Width + 72;
			g.DrawString("Unit Price", _invoiceFont, _blueBrush, xUnitPrice, _currentY);

			int xQuantity = xUnitPrice + (int)g.MeasureString("Unit Price", _invoiceFont).Width + 4;
			g.DrawString("Quantity", _invoiceFont, _blueBrush, xQuantity, _currentY);

			int xDiscount = xQuantity + (int)g.MeasureString("Quantity", _invoiceFont).Width + 4;
			g.DrawString("Discount", _invoiceFont, _blueBrush, xDiscount, _currentY);

			_amountPosition = xDiscount + (int)g.MeasureString("Discount", _invoiceFont).Width + 4;
			g.DrawString("Extended Price", _invoiceFont, _blueBrush, _amountPosition, _currentY);

			// Set Invoice Table:
			_currentY = _currentY + _invoiceFontHeight + 8;

			while (currentRecord < _recordsPerPage)
			{
				fieldValue = rdrInvoice["ProductID"].ToString();
				g.DrawString(fieldValue, _invoiceFont, _blackBrush, xProductID, _currentY);
				fieldValue = rdrInvoice["ProductName"].ToString();
				// if Length of (Product Name) > 20, Draw 20 character only
				if (fieldValue.Length > 20)
					fieldValue = fieldValue.Remove(20, fieldValue.Length - 20);
				g.DrawString(fieldValue, _invoiceFont, _blackBrush, xProductName, _currentY);
				fieldValue = String.Format("{0:0.00}", rdrInvoice["UnitPrice"]);
				g.DrawString(fieldValue, _invoiceFont, _blackBrush, xUnitPrice, _currentY);
				fieldValue = rdrInvoice["Quantity"].ToString();
				g.DrawString(fieldValue, _invoiceFont, _blackBrush, xQuantity, _currentY);
				fieldValue = String.Format("{0:0.00%}", rdrInvoice["Discount"]);
				g.DrawString(fieldValue, _invoiceFont, _blackBrush, xDiscount, _currentY);

				Amount = Convert.ToDecimal(rdrInvoice["ExtendedPrice"]);
				// Format Extended Price and Align to Right:
				fieldValue = String.Format("{0:0.00}", Amount);
				int xAmount = _amountPosition + (int)g.MeasureString("Extended Price", _invoiceFont).Width;
				xAmount = xAmount - (int)g.MeasureString(fieldValue, _invoiceFont).Width;
				g.DrawString(fieldValue, _invoiceFont, _blackBrush, xAmount, _currentY);
				_currentY = _currentY + _invoiceFontHeight;

				if (!rdrInvoice.Read())
				{
					StopReading = true;
					break;
				}

				currentRecord++;
			}

			if (currentRecord < _recordsPerPage)
				e.HasMorePages = false;
			else
				e.HasMorePages = true;

			if (StopReading)
			{
				rdrInvoice.Close();
				cnn.Close();
				SetInvoiceTotal(g);
			}

			g.Dispose();
		}

		private void SetInvoiceTotal(Graphics g)
		{// Set Invoice Total:
			// Draw line:
			_currentY = _currentY + 8;
			g.DrawLine(new Pen(Brushes.Black), _leftMargin, _currentY, _rightMargin, _currentY);
			// Get Right Edge of Invoice:
			int xRightEdg = _amountPosition + (int)g.MeasureString("Extended Price", _invoiceFont).Width;

			// Write Sub Total:
			int xSubTotal = _amountPosition - (int)g.MeasureString("Sub Total", _invoiceFont).Width;
			_currentY = _currentY + 8;
			g.DrawString("Sub Total", _invoiceFont, _redBrush, xSubTotal, _currentY);
			string TotalValue = String.Format("{0:0.00}", _subTotal);
			int xTotalValue = xRightEdg - (int)g.MeasureString(TotalValue, _invoiceFont).Width;
			g.DrawString(TotalValue, _invoiceFont, _blackBrush, xTotalValue, _currentY);

			// Write Order Freight:
			int xOrderFreight = _amountPosition - (int)g.MeasureString("Order Freight", _invoiceFont).Width;
			_currentY = _currentY + _invoiceFontHeight;
			g.DrawString("Order Freight", _invoiceFont, _redBrush, xOrderFreight, _currentY);
			string FreightValue = String.Format("{0:0.00}", _saleFreight);
			int xFreight = xRightEdg - (int)g.MeasureString(FreightValue, _invoiceFont).Width;
			g.DrawString(FreightValue, _invoiceFont, _blackBrush, xFreight, _currentY);

			// Write Invoice Total:
			int xInvoiceTotal = _amountPosition - (int)g.MeasureString("Invoice Total", _invoiceFont).Width;
			_currentY = _currentY + _invoiceFontHeight;
			g.DrawString("Invoice Total", _invoiceFont, _redBrush, xInvoiceTotal, _currentY);
			string InvoiceValue = String.Format("{0:0.00}", _invoiceTotal);
			int xInvoiceValue = xRightEdg - (int)g.MeasureString(InvoiceValue, _invoiceFont).Width;
			g.DrawString(InvoiceValue, _invoiceFont, _blackBrush, xInvoiceValue, _currentY);
		}

		private void ReadInvoiceHead()
		{
			//Titles and Image of invoice:
			InvTitle = "International Food Company";
			InvSubTitle1 = "23 Abo Naga street";
			InvSubTitle2 = "Cairo, Egypt";
			InvSubTitle3 = "Phone 2233445566";
			InvImage = Application.StartupPath + @"\Images\" + "InvPic.jpg";
		}

		private void ReadInvoiceData()
		{
			//cnn.Open();
			//rdrInvoice = cmd.ExecuteReader();
			//rdrInvoice.Read();
		}

		private void ItemPerPageInput_Leave(object sender, EventArgs e)
		{
			string temp=ItemPerPageInput.Text.Trim();
			if (temp.Length < 1)
			{
				_recordsPerPage = 20;
				ItemPerPageInput.Text = _recordsPerPage.ToString();
			}
			else
			{
				try
				{
					_recordsPerPage = Convert.ToInt32(ItemPerPageInput.Text);
				}
				catch (Exception ex)
				{
					msg.Text = "Invalid item per page value.";
					ItemPerPageInput.Focus();
				}
			}
		}

		private void PagesSelect_SelectedIndexChanged(object sender, EventArgs e)
		{
			_currentPage = Convert.ToInt32(((ComboBox)sender).SelectedValue);
		}
	}
}
